﻿using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.IO;

namespace RentIt06
{
    [ServiceContract(Namespace = "RentIt06", SessionMode = SessionMode.Required)]
    public interface IUserSession
    {
        /// <summary>
        /// Logout; Ending the session.
        /// </summary>
        [OperationContract(IsInitiating = false, IsTerminating = true)]
        void Logout();

        /// <summary>
        /// Login; Starting a new session.
        /// </summary>
        /// <param name="email">The email to login with</param>
        /// <param name="password">The password</param>
        [OperationContract(IsInitiating = true, IsTerminating = false)]
        Account Login(string email, string password);

        /// <summary>
        /// Reads the account currently logged in.
        /// </summary>
        /// <returns>The currently logged in account</returns>
        [OperationContract(IsInitiating = false, IsTerminating = false)]
        Account ReadMyAccount();

        /// <summary>
        /// Update the account that is currently logged in with the new information given.
        /// </summary>
        /// <param name="info"></param>
        /// <param name="password"></param>
        [OperationContract(IsInitiating = false, IsTerminating = false)]
        void UpdateAccount(Account info, string password);

        /// <summary>
        /// Change the password that is used with the currently logged in account.
        /// </summary>
        /// <param name="oldPassword">The current password</param>
        /// <param name="newPassword">The new password to be set</param>
        [OperationContract(IsInitiating = false, IsTerminating = false)]
        void ChangePassword(string oldPassword, string newPassword);

        /// <summary>
        /// Deletes the current users account and ends the current session.
        /// </summary>
        /// <param name="password">The password of the current account</param>
        [OperationContract(IsInitiating = false, IsTerminating = true)]
        void DeleteMyAccount(string password);

        // Read media for all access levels
        /// <summary>
        /// Exposes the media object associated with the given id.
        /// Admins and publishers with ownership over the given media, 
        /// will be able to read medias that are not published.
        /// </summary>
        /// <param name="id">The id of the media object to read.</param>
        /// <returns>The media with the given id.</returns>
        [OperationContract(IsInitiating = false, IsTerminating = false)]
        [Obsolete("Use readmedia in PublisherSession or use the media object returned by other methods")]
        Media ReadMedia(int id);

        /// <summary>
        /// Search for media files available on the server.
        /// </summary>
        /// <remarks>
        /// From the client's perspective, this method is intended for use both for searching
        /// and browsing. When searching, the search parameters chosen by the user are simply
        /// passed directly into the method.
        /// When browsing, the client has a set of predefined search configurations for various
        /// needs, e.g. one for generating a frontpage.
        /// </remarks>
        /// <param name="SearchString">A whitespace (or comma) separated list of search words to search for
        /// in either the title, author or category of each media object.
        /// The more of these that are matched for a given media, the higher it ranks in the returned list.
        /// Default is an empty string.</param>
        /// <param name="OrderBy">The SearchOrder by which to sort the results (this order is secondary to SearchString relevance).
        /// Default is order by Title.</param>
        /// <param name="FilterBy">A list of media types allowed/disallowed in the results. Default is an emtpy list.</param>
        /// <param name="InclusiveFiltering">Whether the filter list should be inclusive or exclusive.
        /// Default is false, meaning exclusive filtering.</param>
        /// <param name="Ascending">Whether to sort ascending or not. Default is false.</param>
        /// <param name="Availability">The SearchAvailability by which to filter the results. Default is Both.</param>
        /// <param name="ResultLimit">The upper limit on results returned. Default is unlimited.</param>
        /// <returns>The search result as a list of media objects.</returns>
        [OperationContract(IsInitiating = false, IsTerminating = false)]
        List<Media> SearchProduct(SearchParameters parameters);

        /// <summary>
        /// Rents the given media for the currently logged on account.
        /// </summary>
        /// <remarks>
        /// A rented media is made available for limitless download for the rentee
        /// for the entire period of the rental.
        /// A period of rental is 48 hours.
        /// The rental price associated with the rented product is immediately
        /// subtracted from the rentee's account.
        /// </remarks>
        /// <param name="id">The id of the media.</param>
        [OperationContract(IsInitiating = false, IsTerminating = false)]
        void RentProduct(int id);

        /// <summary>
        /// Purchases the given media for the currently logged on account.
        /// </summary>
        /// <remarks>
        /// A purchased media is made available for limitless download for the rentee
        /// for the entire lifetime of the service.
        /// The buy price associated with the rented product is immediately
        /// subtracted from the rentee's account.
        /// </remarks>
        /// <param name="id">The id of the media.</param>
        [OperationContract(IsInitiating = false, IsTerminating = false)]
        void BuyProduct(int id);

        /// <summary>
        /// Exposes the media files available for download for the currently logged
        /// on account.
        /// </summary>
        /// <returns>A list of media objects.</returns>
        [OperationContract(IsInitiating = false, IsTerminating = false)]
        List<Media> ReadDownloadableProducts();

        /// <summary>
        /// Adds credits to the currently logged on account.
        /// </summary>
        /// <param name="amount">A non-negative number of credits to add.</param>
        /// <param name="creditCard">The credit card to be billed for the purchase of credits.</param>
        /// <param name="saveCreditCard">Whether to save the given credit card for future use.</param>
        [OperationContract(IsInitiating = false, IsTerminating = false)]
        void AddCredit(decimal amount, CreditCardInformations creditCard, bool saveCreditCard);

        /// <summary>
        /// Deletes all information about the currently active credit card for the
        /// currently logged on user.
        /// </summary>
        [OperationContract(IsInitiating = false, IsTerminating = false)]
        void DeleteCreditCardInformation();

        /// <summary>
        /// Exposes the purchase and rental history of the currently logged on user.
        /// </summary>
        /// <returns>A list of previous purchases/rentals.</returns>
        [OperationContract(IsInitiating = false, IsTerminating = false)]
        List<Purchase> ReadPreviousPurchases();

        /// <summary>
        /// Provides a download token for the given media file.
        /// This requires that the logged in user has bought or rented the product.
        /// </summary>
        /// <remarks>
        /// The token can be used in conjunction with the FileService to download the file
        /// associated with the media.
        /// The token will expire after 30 minutes.
        /// </remarks>
        /// <param name="id">The ID of the media file to provide a download token for.</param>
        /// <returns>The token that is to be provided to the DownloadMedia operation of the FileService.</returns>
        [OperationContract(IsInitiating = false, IsTerminating = false)]
        int GetDownloadToken(int id);
    }
}
